// 一个基于TCP/1P的大并发服务器，可以同时接入多个客户端进行通信。
// 要求：客户端接入服务器，客户端向服务器发消息，服务器接收消息并显示

// server.cpp
#include <iostream>
#include <thread>
#include <vector>
#include <mutex>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>

#define PORT 8080
#define BUFFER_SIZE 1024
#define MAX_CONNECTIONS 10

std::mutex printMutex; // 用于线程安全的打印

void handleClient(int clientSocket)
{
    char buffer[BUFFER_SIZE];

    while (true)
    {
        // 清空缓冲区
        memset(buffer, 0, BUFFER_SIZE);

        // 接收客户端消息
        int bytesReceived = recv(clientSocket, buffer, BUFFER_SIZE, 0);
        if (bytesReceived <= 0)
        {
            std::lock_guard<std::mutex> guard(printMutex);
            std::cout << "Client disconnected" << std::endl;
            break;
        }

        // 显示客户端消息
        {
            std::lock_guard<std::mutex> guard(printMutex);
            std::cout << "Received message: " << buffer << std::endl;
        }
    }

    close(clientSocket);
}

int main()
{
    int serverSocket;
    struct sockaddr_in serverAddr, clientAddr;
    socklen_t clientAddrLen = sizeof(clientAddr);

    // 创建服务器套接字
    serverSocket = socket(AF_INET, SOCK_STREAM, 0);
    if (serverSocket == -1)
    {
        std::cerr << "Socket creation failed" << std::endl;
        return -1;
    }

    // 绑定服务器地址和端口
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_addr.s_addr = INADDR_ANY;
    serverAddr.sin_port = htons(PORT);
    if (bind(serverSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0)
    {
        std::cerr << "Bind failed" << std::endl;
        close(serverSocket);
        return -1;
    }

    // 监听连接
    if (listen(serverSocket, MAX_CONNECTIONS) < 0)
    {
        std::cerr << "Listen failed" << std::endl;
        close(serverSocket);
        return -1;
    }

    std::cout << "Server listening on port " << PORT << "..." << std::endl;

    // 接收多个客户端
    while (true)
    {
        int clientSocket = accept(serverSocket, (struct sockaddr *)&clientAddr, &clientAddrLen);
        if (clientSocket < 0)
        {
            std::cerr << "Client accept failed" << std::endl;
            continue;
        }

        {
            std::lock_guard<std::mutex> guard(printMutex);
            std::cout << "Connected to client: " << inet_ntoa(clientAddr.sin_addr)
                      << ":" << ntohs(clientAddr.sin_port) << std::endl;
        }

        // 创建新线程处理客户端
        std::thread clientThread(handleClient, clientSocket);
        clientThread.detach(); // 分离线程，允许线程独立执行
    }

    close(serverSocket);
    return 0;
}

// client.cpp
#include <iostream>
#include <cstring>
#include <arpa/inet.h>
#include <unistd.h>

#define SERVER_IP "127.0.0.1"
#define SERVER_PORT 8080
#define BUFFER_SIZE 1024

int main()
{
    int sock;
    struct sockaddr_in serverAddr;

    // 创建客户端套接字
    sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock < 0)
    {
        std::cerr << "Socket creation error" << std::endl;
        return -1;
    }

    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(SERVER_PORT);

    // 连接到服务器
    if (inet_pton(AF_INET, SERVER_IP, &serverAddr.sin_addr) <= 0)
    {
        std::cerr << "Invalid address/ Address not supported" << std::endl;
        close(sock);
        return -1;
    }

    if (connect(sock, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0)
    {
        std::cerr << "Connection Failed" << std::endl;
        close(sock);
        return -1;
    }

    std::cout << "Connected to the server." << std::endl;

    // 循环发送消息
    while (true)
    {
        std::string message;
        std::cout << "Enter message to send: ";
        std::getline(std::cin, message);

        if (message == "exit")
        {
            break;
        }

        send(sock, message.c_str(), message.size(), 0);
    }

    close(sock);
    return 0;
}